package com.ybb.vue.common.scheduletask;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ybb.vue.common.util.MailUtils;
import com.ybb.vue.common.util.RandCreateHealStatusUtils;
import com.ybb.vue.common.webSocket.WebSocket;
import com.ybb.vue.domain.vo.AlarmMessageVo;
import com.ybb.vue.entity.EpmAlarmNotes;
import com.ybb.vue.entity.EpmAlarmRule;
import com.ybb.vue.entity.EpmResident;
import com.ybb.vue.entity.Message;
import com.ybb.vue.mapper.EpmAlarmRuleMapper;
import com.ybb.vue.mapper.EpmResidentMapper;
import com.ybb.vue.service.EpmAlarmNotesService;
import com.ybb.vue.service.EpmResidentService;
import com.ybb.vue.service.MessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
public class ScheduleTask {

    @Autowired
    private MailUtils mailUtils;

    @Autowired
    private EpmAlarmRuleMapper epmAlarmRuleMapper;

    @Autowired
    private EpmResidentMapper epmResidentMapper;

    @Autowired
    private EpmAlarmNotesService epmAlarmNotesService;

    @Autowired
    private EpmResidentService epmResidentService;

    @Autowired
    private MessageService messageService;

    @Autowired
    private WebSocket webSocket;

    /**
     * 模拟推送居民健康信息，每天每隔1小时执行一次，
     */
    @Scheduled(cron = "0 0 */1 * * ?")
//    @Scheduled(cron =  "0 0/2 * * * ?")
    public void healthStatus(){
        // 查询出所有规则
        List<EpmAlarmRule> alarmRuleList = epmAlarmRuleMapper.selectList(new QueryWrapper<EpmAlarmRule>().lambda().eq(EpmAlarmRule::getStatus, "0"));
        // 查询所有的居民
        List<EpmResident> epmResidents = epmResidentMapper.selectList(new QueryWrapper<EpmResident>(null));
        // 告警记录
        List<EpmAlarmNotes> epmAlarmNotesList = new ArrayList<>();
        // 告警消息
        List<Message> messageList = new ArrayList<>();
        // 告警消息发送人
        Set<String> messagePerson = new HashSet<>();
        // 邮件发送内容
        StringBuffer content = new StringBuffer();
        // 邮件发送地址
        Set<String> emailSet = new HashSet<>();
        epmResidents.forEach(epmResident -> {
            String healthStatus = RandCreateHealStatusUtils.getHealStatus();
            // 为黄码
            if ("1".equals(healthStatus)) {
                List<EpmAlarmRule> yellowList = alarmRuleList.stream().filter(e -> e.getAlarmType().equals("0")).collect(Collectors.toList());
                for (EpmAlarmRule epmAlarmRule : yellowList) {
                    // 生成告警记录
                    EpmAlarmNotes epmAlarmNotes = new EpmAlarmNotes();
                    epmAlarmNotes.setAlarmName(epmAlarmRule.getAlarmName());
                    epmAlarmNotes.setAlarmType(epmAlarmRule.getAlarmType());
                    epmAlarmNotes.setNoticeObject(epmAlarmRule.getNoticeObject());
                    epmAlarmNotes.setEmail(epmAlarmRule.getEmail());
                    epmAlarmNotes.setAlarmTime(new Date());
                    epmAlarmNotes.setAlarmContent(epmResident.getName()+"健康码为黄码");
                    epmAlarmNotes.setResidentName(epmResident.getName());
                    epmAlarmNotesList.add(epmAlarmNotes);
                    content.append("住在"+epmResident.getBuilding()+epmResident.getUnit()+epmResident.getHouseNumber()+"的【"+epmResident.getName() + "】的健康码为【黄码】，请及时处理").append("\n").append("\n");

                    String[] emailString = epmAlarmRule.getEmail().split(",");
                    for (String s : emailString) {
                        emailSet.add(s);
                    }
                    // 告警消息
                    String[] alarmObject = epmAlarmRule.getNoticeObject().split(",");
                    for (String object : alarmObject) {
                        // 存入数据库
                        Message message = new Message();
                        message.setResidentId(epmResident.getId());
                        message.setAlarmType("0");
                        message.setMessageContent("尊敬的【"+object+"】您好，住在"+epmResident.getBuilding()+epmResident.getUnit()+epmResident.getHouseNumber()+"的【"+epmResident.getName() + "】的健康码为【黄码】，请及时处理");
                        message.setReceivePerson(object);
                        message.setMessageTime(new Date());
                        message.setStatus("0");
                        messageList.add(message);
                        // 发送websocket消息（消息接收人）
                        messagePerson.add(object);
                    }

                }
            }
            // 为红码
            if ("2".equals(healthStatus)) {
                List<EpmAlarmRule> redList = alarmRuleList.stream().filter(e -> e.getAlarmType().equals("1")).collect(Collectors.toList());
                for (EpmAlarmRule epmAlarmRule : redList) {
                    // 生成告警记录
                    EpmAlarmNotes epmAlarmNotes = new EpmAlarmNotes();
                    epmAlarmNotes.setAlarmName(epmAlarmRule.getAlarmName());
                    epmAlarmNotes.setAlarmType(epmAlarmRule.getAlarmType());
                    epmAlarmNotes.setNoticeObject(epmAlarmRule.getNoticeObject());
                    epmAlarmNotes.setEmail(epmAlarmRule.getEmail());
                    epmAlarmNotes.setAlarmTime(new Date());
                    epmAlarmNotes.setAlarmContent(epmResident.getName()+"健康码为红码");
                    epmAlarmNotes.setResidentName(epmResident.getName());
                    epmAlarmNotesList.add(epmAlarmNotes);
                    content.append("住在"+epmResident.getBuilding()+epmResident.getUnit()+epmResident.getHouseNumber()+"的【"+epmResident.getName() + "】的健康码为【红码】，请及时处理").append("\n").append("\n");

                    String[] emailString = epmAlarmRule.getEmail().split(",");
                    for (String s : emailString) {
                        emailSet.add(s);
                    }
                    // 告警消息
                    String[] alarmObject = epmAlarmRule.getNoticeObject().split(",");
                    for (String object : alarmObject) {
                        // 存入数据库
                        Message message = new Message();
                        message.setResidentId(epmResident.getId());
                        message.setAlarmType("1");
                        message.setMessageContent("尊敬的【"+object+"】您好，住在"+epmResident.getBuilding()+epmResident.getUnit()+epmResident.getHouseNumber()+"的【"+epmResident.getName() + "】的健康码为【红码】，请及时处理");
                        message.setReceivePerson(object);
                        message.setMessageTime(new Date());
                        message.setStatus("0");
                        messageList.add(message);
                        // 发送websocket消息（消息接收人）
                        messagePerson.add(object);
                    }
                }
            }
            // 为未知弹窗
            if ("3".equals(healthStatus)) {
                List<EpmAlarmRule> noDigList = alarmRuleList.stream().filter(e -> e.getAlarmType().equals("2")).collect(Collectors.toList());
                for (EpmAlarmRule epmAlarmRule : noDigList) {
                    // 生成告警记录
                    EpmAlarmNotes epmAlarmNotes = new EpmAlarmNotes();
                    epmAlarmNotes.setAlarmName(epmAlarmRule.getAlarmName());
                    epmAlarmNotes.setAlarmType(epmAlarmRule.getAlarmType());
                    epmAlarmNotes.setNoticeObject(epmAlarmRule.getNoticeObject());
                    epmAlarmNotes.setEmail(epmAlarmRule.getEmail());
                    epmAlarmNotes.setAlarmTime(new Date());
                    epmAlarmNotes.setAlarmContent(epmResident.getName()+"健康码未知弹窗");
                    epmAlarmNotes.setResidentName(epmResident.getName());
                    epmAlarmNotesList.add(epmAlarmNotes);
                    content.append("住在"+epmResident.getBuilding()+epmResident.getUnit()+epmResident.getHouseNumber()+"的【"+epmResident.getName() + "】的健康码为【未知弹窗】，请及时处理").append("\n").append("\n");

                    String[] emailString = epmAlarmRule.getEmail().split(",");
                    for (String s : emailString) {
                        emailSet.add(s);
                    }
                    // 告警消息
                    String[] alarmObject = epmAlarmRule.getNoticeObject().split(",");
                    for (String object : alarmObject) {
                        // 存入数据库
                        Message message = new Message();
                        message.setResidentId(epmResident.getId());
                        message.setAlarmType("2");
                        message.setMessageContent("尊敬的【"+object+"】您好，住在"+epmResident.getBuilding()+epmResident.getUnit()+epmResident.getHouseNumber()+"的【"+epmResident.getName() + "】的健康码为【未知弹窗】，请及时处理");
                        message.setReceivePerson(object);
                        message.setMessageTime(new Date());
                        message.setStatus("0");
                        messageList.add(message);
                        // 发送websocket消息（消息接收人）
                        messagePerson.add(object);
                    }
                }
            }
            // 为未申请
            if ("4".equals(healthStatus)) {
                List<EpmAlarmRule> noList = alarmRuleList.stream().filter(e -> e.getAlarmType().equals("3")).collect(Collectors.toList());
                for (EpmAlarmRule epmAlarmRule : noList) {
                    // 生成告警记录
                    EpmAlarmNotes epmAlarmNotes = new EpmAlarmNotes();
                    epmAlarmNotes.setAlarmName(epmAlarmRule.getAlarmName());
                    epmAlarmNotes.setAlarmType(epmAlarmRule.getAlarmType());
                    epmAlarmNotes.setNoticeObject(epmAlarmRule.getNoticeObject());
                    epmAlarmNotes.setEmail(epmAlarmRule.getEmail());
                    epmAlarmNotes.setAlarmTime(new Date());
                    epmAlarmNotes.setAlarmContent(epmResident.getName()+"健康码未申请");
                    epmAlarmNotes.setResidentName(epmResident.getName());
                    epmAlarmNotesList.add(epmAlarmNotes);
                    content.append("住在"+epmResident.getBuilding()+epmResident.getUnit()+epmResident.getHouseNumber()+"的【"+epmResident.getName() + "】的健康码为【未申请】，请及时处理").append("\n").append("\n");

                    String[] emailString = epmAlarmRule.getEmail().split(",");
                    for (String s : emailString) {
                        emailSet.add(s);
                    }
                    // 告警消息
                    String[] alarmObject = epmAlarmRule.getNoticeObject().split(",");
                    for (String object : alarmObject) {
                        // 存入数据库
                        Message message = new Message();
                        message.setResidentId(epmResident.getId());
                        message.setAlarmType("3");
                        message.setMessageContent("尊敬的【"+object+"】您好，住在"+epmResident.getBuilding()+epmResident.getUnit()+epmResident.getHouseNumber()+"的【"+epmResident.getName() + "】的健康码为【未申请】，请及时处理");
                        message.setReceivePerson(object);
                        message.setMessageTime(new Date());
                        message.setStatus("0");
                        messageList.add(message);
                        // 发送websocket消息（消息接收人）
                        messagePerson.add(object);
                    }
                }
            }
            epmResident.setHealthStatus(healthStatus);
        });

        // 发送邮件
        if (emailSet.size() > 0) {
            // 更新居民健康码
            epmResidentService.updateBatchById(epmResidents);
            // 保存告警记录
            epmAlarmNotesService.saveBatch(epmAlarmNotesList);
            // 发送邮件
            String[] emailTos = emailSet.toArray(new String[emailSet.size()]);
            mailUtils.sendSimpleEmail(emailTos,"小区居民健康码信息异常信息",content.toString());
            System.out.println("定时任务已执行，执行时间为：" + new Date());
        }

        // 告警消息存入数据库并发送消息
        if (messagePerson.size() > 0) {
            messageService.saveBatch(messageList);
            // 超级管理员必须发送消息
            messagePerson.add("admin");
            messagePerson.forEach(person->{
                AlarmMessageVo alarmMessageVo = new AlarmMessageVo();
                alarmMessageVo.setMessage("尊敬的管理员，您有有新的告警消息");
                alarmMessageVo.setReturnMessageType("B");
                webSocket.sendMessageToTargetObject(person, alarmMessageVo);
            });
        }
    }

}

